/* lib
 ************************************************
 * Object-MD
 * Object Oriented Molecular Dynamics Program
 * 
 * (c)Yudi Rosandi, 2005
 *
 * Version 0.1 (05.2006)
 *
 * Project started on July 2005.
 *
 ************************************************
 * Object-MD Header file
 *
 * Configuration file reader
 *
*/

#ifndef _CFG_READER_H_
#define _CFG_READER_H_

#include <fstream>
#include <vector>
#include <string>
#include <sstream>

using std::vector;
using std::string;
using std::istringstream;
/*
	Eratum:  
		- << operator in the same line will fail while using
		  string functions, because it uses the same string buffer.
*/

//!Configuration file reader
/**
 * ConfigReader class is an independent class which has duty to
 * read all the tokens from the configuration file. The file consist of
 * 'tag' and 'value' tokens, writen in the following format:
 *
 * tag = value
 * 
 * Value can be one of three types, double (decimal number), integer (number), 
 * boolean (true or false), or a three number vector (see GetVector()).
 *
 * The tag and the corresponding value are stored in the c++ vector-list form.
 * User can access the value by refferencing the tag name with help of
 * four member functions: GetDouble(), GetInt(), GetVector(), and GetBool().
 *
*/

class ConfigReader {
private:
	char ConfigFile[128];
	vector<string> Tag;
	vector<string> Value;
	istringstream CfgStream;

public:
	ConfigReader(){ConfigFile[0]='\0';}
	ConfigReader(const string cfg_fl, bool extract=false, const char* magicword=NULL);	
	~ConfigReader();
	
	static char*  TagMember(const char* tag, const char* member);
	
	// first member is 1, member=0 means tag without member
	static char*  TagMember(const char* tag, const int member);
	
	void   ReadFile(const string cfg_fl, bool setname=true);
	bool   ExtractFile(const string txt_file, const char* magicword=NULL);
	bool   Exist(const char* tag);
	bool   ExistMember(const char* tag, const int member) 
	       {return Exist(TagMember(tag, member));}
	bool   ExistMember(const char* tag, const char* member) 
	       {return Exist(TagMember(tag, member));}

	double GetDouble(const char* tag);
	bool   GetBool(const char* tag);
	int    GetInt(const char* tag);
	istringstream& GetStringStream(const char* tag=NULL);
	char*  GetString(const char* tag);
	char*  GetString(const char* tag, char* streturn);
	char*  GetStringLast(const char* tag, const int startpos);
	char*  GetStringLast(const char* tag, const int startpos, char* streturn);
	double GetVector(const char* tag, const int elem);
	void   GetVector(const char* tag, double &x, double &y, double &z);
	char*  GetWord(const char* tag, const int wordpos);
	char*  GetWord(const char* tag, const int wordpos, char* streturn);
	
	size_t  GetVectorSize(const char* tag);
	size_t  GetMemberSize(const char* tag);
	
	double* GetVectorDouble(const char* tag, size_t &len);
	int*    GetVectorInt(const char* tag, size_t &len);
	
	void   Set(const char* tag, const double value);
	void   Set(const char* tag, const int value);
	void   Set(const char* tag, const bool value);
	void   Set(const char* tag, const char* value);
	
	void Dump(const char* fname);
	
	char* GetFilename() {return ConfigFile;}
	// Static members
	static void Trim(string& vst);
};

#endif
